package cn.tpshion.config.service;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.tpshion.config.common.AssertUtil;
import cn.tpshion.config.service.support.AuthInfo;
import cn.tpshion.config.service.support.AuthType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.ConfigurableEnvironment;

import java.util.HashMap;
import java.util.Map;

/**
 * 配置中心认证服务
 */
public class ConfigAuthService {

    private static final Logger log = LoggerFactory.getLogger(ConfigAuthService.class);

    private ConfigurableEnvironment environment;

    private String host;

    /**
     * 配置中心认证，获取token
     */
    public String auth(){
        // 配置中心服务端地址
        String host = environment.getProperty("config.host");
        // 认证类型
        String type = environment.getProperty("config.type");
        // 检查配置
        AssertUtil.notEmpty(host,"config.host配置不能为空");
        this.host = host;
        AssertUtil.notEmpty(type,"config.type配置不能为空");

        // 检查授权类型
        AssertUtil.isTrue(AuthType.checkType(type),"config.type类型错误，只能配置password或者code");

        AuthInfo authInfo = new AuthInfo();
        authInfo.setType(type);

        // 判断授权类型
        if(AuthType.PASSWORD.getType().equals(type)){
            String username = environment.getProperty("config.username");
            String password = environment.getProperty("config.password");
            AssertUtil.notEmpty(username,"config.username不能为空");
            AssertUtil.notEmpty(password,"config.password不能为空");

            authInfo.setUsername(username);
            authInfo.setPassword(password);
        }

        if(AuthType.CODE.getType().equals(type)){
            String secretkey = environment.getProperty("config.secretkey");
            AssertUtil.notEmpty(secretkey,"config.secretkey不能为空");

            authInfo.setSecretkey(secretkey);
        }

        return doLogin(authInfo);
    }

    /**
     * 执行登录方法
     * @param authInfo
     * @return
     */
    private String doLogin(AuthInfo authInfo){
        String url = host + "/auth/login";
        log.info("config doLogin request url:{} param:{}",url,JSONUtil.toJsonStr(authInfo));
        String result = HttpRequest.post(url)
                .body(JSONUtil.toJsonStr(authInfo))
                .execute().body();
        log.info("config doLogin response result:{}",result);
        String data = (String) checkResult(result);
        return data;
    }

    /**
     * 获取配置中心zookeeper地址
     * @param token
     * @return
     */
    public String getConfigHost(String token){
        AssertUtil.notEmpty(token,"token不能为空");
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("token", token);
        String url = host + "/auth/getHost";
        log.info("getConfigHost request url:{} param:{}",url,paramMap);
        String result = HttpUtil.get(url, paramMap);
        log.info("getConfigHost response result:{}",result);
        String data = (String) checkResult(result);
        return data;
    }

    private Object checkResult(String result){
        AssertUtil.notEmpty(result,"请求配置中心失败");
        JSONObject jsonObject = JSONUtil.parseObj(result);
        String code = (String) jsonObject.get("code");
        AssertUtil.isTrue("00".equals(code),(String) jsonObject.get("msg"));
        return jsonObject.get("data");
    }

    public ConfigurableEnvironment getEnvironment() {
        return environment;
    }

    public void setEnvironment(ConfigurableEnvironment environment) {
        this.environment = environment;
    }
}
